Skip to main content

core/iter/adapters/
fuse.rs

1use crate::intrinsics;
2use crate::iter::adapters::SourceIter;
3use crate::iter::adapters::zip::try_get_unchecked;
4use crate::iter::{
5    FusedIterator, TrustedFused, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
6};
7use crate::num::NonZero;
8use crate::ops::Try;
9
10/// An iterator that yields `None` forever after the underlying iterator
11/// yields `None` once.
12///
13/// This `struct` is created by [`Iterator::fuse`]. See its documentation
14/// for more.
15#[derive(Clone, Debug)]
16#[must_use = "iterators are lazy and do nothing unless consumed"]
17#[stable(feature = "rust1", since = "1.0.0")]
18pub struct Fuse<I> {
19    // NOTE: for `I: FusedIterator`, we never bother setting `None`, but
20    // we still have to be prepared for that state due to variance.
21    // See rust-lang/rust#85863
22    iter: Option<I>,
23}
24impl<I> Fuse<I> {
25    pub(in crate::iter) const fn new(iter: I) -> Fuse<I> {
26        Fuse { iter: Some(iter) }
27    }
28
29    pub(crate) fn into_inner(self) -> Option<I> {
30        self.iter
31    }
32}
33
34#[stable(feature = "fused", since = "1.26.0")]
35impl<I> FusedIterator for Fuse<I> where I: Iterator {}
36
37#[unstable(issue = "none", feature = "trusted_fused")]
38unsafe impl<I> TrustedFused for Fuse<I> where I: TrustedFused {}
39
40// Any specialized implementation here is made internal
41// to avoid exposing default fns outside this trait.
42#[stable(feature = "rust1", since = "1.0.0")]
43impl<I> Iterator for Fuse<I>
44where
45    I: Iterator,
46{
47    type Item = <I as Iterator>::Item;
48
49    #[inline]
50    fn next(&mut self) -> Option<Self::Item> {
51        FuseImpl::next(self)
52    }
53
54    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
55        FuseImpl::advance_by(self, n)
56    }
57
58    #[inline]
59    fn nth(&mut self, n: usize) -> Option<I::Item> {
60        FuseImpl::nth(self, n)
61    }
62
63    #[inline]
64    fn last(self) -> Option<Self::Item> {
65        match self.iter {
66            Some(iter) => iter.last(),
67            None => None,
68        }
69    }
70
71    #[inline]
72    fn count(self) -> usize {
73        match self.iter {
74            Some(iter) => iter.count(),
75            None => 0,
76        }
77    }
78
79    #[inline]
80    fn size_hint(&self) -> (usize, Option<usize>) {
81        match self.iter {
82            Some(ref iter) => iter.size_hint(),
83            None => (0, Some(0)),
84        }
85    }
86
87    #[inline]
88    fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
89    where
90        Self: Sized,
91        Fold: FnMut(Acc, Self::Item) -> R,
92        R: Try<Output = Acc>,
93    {
94        FuseImpl::try_fold(self, acc, fold)
95    }
96
97    #[inline]
98    fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
99    where
100        Fold: FnMut(Acc, Self::Item) -> Acc,
101    {
102        if let Some(iter) = self.iter {
103            acc = iter.fold(acc, fold);
104        }
105        acc
106    }
107
108    #[inline]
109    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
110    where
111        P: FnMut(&Self::Item) -> bool,
112    {
113        FuseImpl::find(self, predicate)
114    }
115
116    #[inline]
117    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
118    where
119        Self: TrustedRandomAccessNoCoerce,
120    {
121        match self.iter {
122            // SAFETY: the caller must uphold the contract for
123            // `Iterator::__iterator_get_unchecked`.
124            Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
125            // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
126            None => unsafe { intrinsics::unreachable() },
127        }
128    }
129}
130
131#[stable(feature = "rust1", since = "1.0.0")]
132impl<I> DoubleEndedIterator for Fuse<I>
133where
134    I: DoubleEndedIterator,
135{
136    #[inline]
137    fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
138        FuseImpl::next_back(self)
139    }
140
141    #[inline]
142    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
143        FuseImpl::advance_back_by(self, n)
144    }
145
146    #[inline]
147    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
148        FuseImpl::nth_back(self, n)
149    }
150
151    #[inline]
152    fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
153    where
154        Self: Sized,
155        Fold: FnMut(Acc, Self::Item) -> R,
156        R: Try<Output = Acc>,
157    {
158        FuseImpl::try_rfold(self, acc, fold)
159    }
160
161    #[inline]
162    fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
163    where
164        Fold: FnMut(Acc, Self::Item) -> Acc,
165    {
166        if let Some(iter) = self.iter {
167            acc = iter.rfold(acc, fold);
168        }
169        acc
170    }
171
172    #[inline]
173    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
174    where
175        P: FnMut(&Self::Item) -> bool,
176    {
177        FuseImpl::rfind(self, predicate)
178    }
179}
180
181#[stable(feature = "rust1", since = "1.0.0")]
182impl<I> ExactSizeIterator for Fuse<I>
183where
184    I: ExactSizeIterator,
185{
186    fn len(&self) -> usize {
187        match self.iter {
188            Some(ref iter) => iter.len(),
189            None => 0,
190        }
191    }
192
193    fn is_empty(&self) -> bool {
194        match self.iter {
195            Some(ref iter) => iter.is_empty(),
196            None => true,
197        }
198    }
199}
200
201#[stable(feature = "default_iters", since = "1.70.0")]
202impl<I: Default> Default for Fuse<I> {
203    /// Creates a `Fuse` iterator from the default value of `I`.
204    ///
205    /// ```
206    /// # use core::slice;
207    /// # use std::iter::Fuse;
208    /// let iter: Fuse<slice::Iter<'_, u8>> = Default::default();
209    /// assert_eq!(iter.len(), 0);
210    /// ```
211    ///
212    /// This is equivalent to `I::default().fuse()`[^fuse_note]; e.g. if
213    /// `I::default()` is not an empty iterator, then this will not be
214    /// an empty iterator.
215    ///
216    /// ```
217    /// # use std::iter::Fuse;
218    /// #[derive(Default)]
219    /// struct Fourever;
220    ///
221    /// impl Iterator for Fourever {
222    ///     type Item = u32;
223    ///     fn next(&mut self) -> Option<u32> {
224    ///         Some(4)
225    ///     }
226    /// }
227    ///
228    /// let mut iter: Fuse<Fourever> = Default::default();
229    /// assert_eq!(iter.next(), Some(4));
230    /// ```
231    ///
232    /// [^fuse_note]: if `I` does not override `Iterator::fuse`'s default implementation
233    fn default() -> Self {
234        Fuse { iter: Some(I::default()) }
235    }
236}
237
238#[unstable(feature = "trusted_len", issue = "37572")]
239// SAFETY: `TrustedLen` requires that an accurate length is reported via `size_hint()`. As `Fuse`
240// is just forwarding this to the wrapped iterator `I` this property is preserved and it is safe to
241// implement `TrustedLen` here.
242unsafe impl<I> TrustedLen for Fuse<I> where I: TrustedLen {}
243
244#[doc(hidden)]
245#[unstable(feature = "trusted_random_access", issue = "none")]
246// SAFETY: `TrustedRandomAccess` requires that `size_hint()` must be exact and cheap to call, and
247// `Iterator::__iterator_get_unchecked()` must be implemented accordingly.
248//
249// This is safe to implement as `Fuse` is just forwarding these to the wrapped iterator `I`, which
250// preserves these properties.
251unsafe impl<I> TrustedRandomAccess for Fuse<I> where I: TrustedRandomAccess {}
252
253#[doc(hidden)]
254#[unstable(feature = "trusted_random_access", issue = "none")]
255unsafe impl<I> TrustedRandomAccessNoCoerce for Fuse<I>
256where
257    I: TrustedRandomAccessNoCoerce,
258{
259    const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
260}
261
262/// Fuse specialization trait
263///
264/// We only need to worry about `&mut self` methods, which
265/// may exhaust the iterator without consuming it.
266#[doc(hidden)]
267trait FuseImpl<I> {
268    type Item;
269
270    // Functions specific to any normal Iterators
271    fn next(&mut self) -> Option<Self::Item>;
272    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
273    fn nth(&mut self, n: usize) -> Option<Self::Item>;
274    fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
275    where
276        Self: Sized,
277        Fold: FnMut(Acc, Self::Item) -> R,
278        R: Try<Output = Acc>;
279    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
280    where
281        P: FnMut(&Self::Item) -> bool;
282
283    // Functions specific to DoubleEndedIterators
284    fn next_back(&mut self) -> Option<Self::Item>
285    where
286        I: DoubleEndedIterator;
287    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
288    where
289        I: DoubleEndedIterator;
290    fn nth_back(&mut self, n: usize) -> Option<Self::Item>
291    where
292        I: DoubleEndedIterator;
293    fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
294    where
295        Self: Sized,
296        Fold: FnMut(Acc, Self::Item) -> R,
297        R: Try<Output = Acc>,
298        I: DoubleEndedIterator;
299    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
300    where
301        P: FnMut(&Self::Item) -> bool,
302        I: DoubleEndedIterator;
303}
304
305/// General `Fuse` impl which sets `iter = None` when exhausted.
306#[doc(hidden)]
307impl<I> FuseImpl<I> for Fuse<I>
308where
309    I: Iterator,
310{
311    type Item = <I as Iterator>::Item;
312
313    #[inline]
314    default fn next(&mut self) -> Option<<I as Iterator>::Item> {
315        and_then_or_clear(&mut self.iter, Iterator::next)
316    }
317
318    #[inline]
319    default fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
320        let Some(iter) = &mut self.iter else {
321            return match NonZero::new(n) {
322                Some(n) => Err(n),
323                None => Ok(()),
324            };
325        };
326
327        let res = iter.advance_by(n);
328        if res.is_err() {
329            self.iter = None;
330        }
331        res
332    }
333
334    #[inline]
335    default fn nth(&mut self, n: usize) -> Option<I::Item> {
336        and_then_or_clear(&mut self.iter, |iter| iter.nth(n))
337    }
338
339    #[inline]
340    default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
341    where
342        Self: Sized,
343        Fold: FnMut(Acc, Self::Item) -> R,
344        R: Try<Output = Acc>,
345    {
346        if let Some(ref mut iter) = self.iter {
347            acc = iter.try_fold(acc, fold)?;
348            self.iter = None;
349        }
350        try { acc }
351    }
352
353    #[inline]
354    default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
355    where
356        P: FnMut(&Self::Item) -> bool,
357    {
358        and_then_or_clear(&mut self.iter, |iter| iter.find(predicate))
359    }
360
361    #[inline]
362    default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
363    where
364        I: DoubleEndedIterator,
365    {
366        and_then_or_clear(&mut self.iter, |iter| iter.next_back())
367    }
368
369    #[inline]
370    default fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
371    where
372        I: DoubleEndedIterator,
373    {
374        let Some(iter) = &mut self.iter else {
375            return match NonZero::new(n) {
376                Some(n) => Err(n),
377                None => Ok(()),
378            };
379        };
380
381        let res = iter.advance_back_by(n);
382        if res.is_err() {
383            self.iter = None;
384        }
385        res
386    }
387
388    #[inline]
389    default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
390    where
391        I: DoubleEndedIterator,
392    {
393        and_then_or_clear(&mut self.iter, |iter| iter.nth_back(n))
394    }
395
396    #[inline]
397    default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
398    where
399        Self: Sized,
400        Fold: FnMut(Acc, Self::Item) -> R,
401        R: Try<Output = Acc>,
402        I: DoubleEndedIterator,
403    {
404        if let Some(ref mut iter) = self.iter {
405            acc = iter.try_rfold(acc, fold)?;
406            self.iter = None;
407        }
408        try { acc }
409    }
410
411    #[inline]
412    default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
413    where
414        P: FnMut(&Self::Item) -> bool,
415        I: DoubleEndedIterator,
416    {
417        and_then_or_clear(&mut self.iter, |iter| iter.rfind(predicate))
418    }
419}
420
421/// Specialized `Fuse` impl which doesn't bother clearing `iter` when exhausted.
422/// However, we must still be prepared for the possibility that it was already cleared!
423#[doc(hidden)]
424impl<I> FuseImpl<I> for Fuse<I>
425where
426    I: FusedIterator,
427{
428    #[inline]
429    fn next(&mut self) -> Option<<I as Iterator>::Item> {
430        self.iter.as_mut()?.next()
431    }
432
433    #[inline]
434    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
435        match &mut self.iter {
436            Some(iter) => iter.advance_by(n),
437            None => match NonZero::new(n) {
438                Some(n) => Err(n),
439                None => Ok(()),
440            },
441        }
442    }
443
444    #[inline]
445    fn nth(&mut self, n: usize) -> Option<I::Item> {
446        self.iter.as_mut()?.nth(n)
447    }
448
449    #[inline]
450    fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
451    where
452        Self: Sized,
453        Fold: FnMut(Acc, Self::Item) -> R,
454        R: Try<Output = Acc>,
455    {
456        if let Some(ref mut iter) = self.iter {
457            acc = iter.try_fold(acc, fold)?;
458        }
459        try { acc }
460    }
461
462    #[inline]
463    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
464    where
465        P: FnMut(&Self::Item) -> bool,
466    {
467        self.iter.as_mut()?.find(predicate)
468    }
469
470    #[inline]
471    fn next_back(&mut self) -> Option<<I as Iterator>::Item>
472    where
473        I: DoubleEndedIterator,
474    {
475        self.iter.as_mut()?.next_back()
476    }
477
478    #[inline]
479    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
480    where
481        I: DoubleEndedIterator,
482    {
483        match &mut self.iter {
484            Some(iter) => iter.advance_back_by(n),
485            None => match NonZero::new(n) {
486                Some(n) => Err(n),
487                None => Ok(()),
488            },
489        }
490    }
491
492    #[inline]
493    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
494    where
495        I: DoubleEndedIterator,
496    {
497        self.iter.as_mut()?.nth_back(n)
498    }
499
500    #[inline]
501    fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
502    where
503        Self: Sized,
504        Fold: FnMut(Acc, Self::Item) -> R,
505        R: Try<Output = Acc>,
506        I: DoubleEndedIterator,
507    {
508        if let Some(ref mut iter) = self.iter {
509            acc = iter.try_rfold(acc, fold)?;
510        }
511        try { acc }
512    }
513
514    #[inline]
515    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
516    where
517        P: FnMut(&Self::Item) -> bool,
518        I: DoubleEndedIterator,
519    {
520        self.iter.as_mut()?.rfind(predicate)
521    }
522}
523
524// This is used by Flatten's SourceIter impl
525#[unstable(issue = "none", feature = "inplace_iteration")]
526unsafe impl<I> SourceIter for Fuse<I>
527where
528    I: SourceIter + TrustedFused,
529{
530    type Source = I::Source;
531
532    #[inline]
533    unsafe fn as_inner(&mut self) -> &mut I::Source {
534        // SAFETY: unsafe function forwarding to unsafe function with the same requirements.
535        // TrustedFused guarantees that we'll never encounter a case where `self.iter` would
536        // be set to None.
537        unsafe { SourceIter::as_inner(self.iter.as_mut().unwrap_unchecked()) }
538    }
539}
540
541#[inline]
542fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
543    let x = f(opt.as_mut()?);
544    if x.is_none() {
545        *opt = None;
546    }
547    x
548}